package com.unitd.modules.gen.service.impl;

import com.unitd.frame.comm.utils.BeanUtils;
import com.unitd.frame.comm.utils.DateUtils;
import com.unitd.frame.comm.utils.StringUtils;
import com.unitd.frame.mybatis.core.dao.ICrudDao;
import com.unitd.frame.mybatis.core.service.impl.CrudServiceImpl;
import com.unitd.modules.gen.dao.IGenTableColumnDao;
import com.unitd.modules.gen.dao.IGenTableDao;
import com.unitd.modules.gen.entity.GenTable;
import com.unitd.modules.gen.entity.GenTableColumn;
import com.unitd.modules.gen.service.IGenTableService;
import com.unitd.modules.gen.util.GenUtils;
import com.unitd.modules.sys.dao.ISysDictDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * @desc 业务表Service
 * @filename GenTableService.java
 * @copyright www.unitdtech.com
 * @author Hudan
 * @version 1.0
 * @date 2017-04-27
 */
@Service("genTableService")
public class GenTableServiceImpl extends CrudServiceImpl<GenTable, String> implements IGenTableService {

	@Autowired
	private IGenTableDao genTableDao;
	@Autowired
	private IGenTableColumnDao genTableColumnDao;
	@Autowired
	private ISysDictDao sysDictDao;

	/**
	 * @desc 定义成抽象方法, 由子类实现, 完成dao的注入
	 * @return GenericDao实现类
	 */
	@Override
	public ICrudDao<GenTable, String> getDao() {
		return genTableDao;
	}

	/**
	 * @desc 获取单条数据
	 * @param id 主键ID
	 * @return
	 */
	@Override
	public GenTable findBy(String id) {
		// 查询主表及字段列
		GenTable genTable = genTableDao.findBy(id);
		genTable.setColumnList(genTableColumnDao.findListBy(new GenTableColumn(new GenTable(genTable.getId()))));
		return genTable;
	}

	/**
	 * @desc 查询数据列表，如果需要分页，请设置分页对象，如：entity.setPage(new Page<T>());
	 * @param entity 查询参数对象
	 * @return List<Model>
	 */
	@Override
	public List<GenTable> findListBy(GenTable entity) {
		return genTableDao.findListBy(entity);
	}

	/**
	 * @desc 查询所有数据列表
	 * @param entity 查询参数对象
	 * @return List<Model>
	 */
	@Override
	public List<GenTable> findAllData(GenTable entity) {
		return genTableDao.findAllData(entity);
	}

	/**
	 * @desc 根据参数信息,逻辑删除业务表对象信息
	 * @param genTable 业务表对象
	 */
	@Override
	@Transactional(rollbackFor={RuntimeException.class, Exception.class, Throwable.class})
	public int deleteByDelFlag(GenTable genTable) {
		return genTableDao.deleteByDelFlag(genTable);
	}

	/**
	 * @desc 根据数据库表名(单个表名),获取该表对应的数据
	 * @param tableName 数据库表名(单个表名)
	 * @return
	 */
	@Override
	public GenTable findByTableName(String tableName) {
		return genTableDao.findByTableName(tableName);
	}

	/**
	 * @desc 根据数据库表名(多个表名,用,进行分割),获取该表对应的数据
	 * @param tableNames 数据库表名(多个表名,用,进行分割
	 * @return
	 */
	@Override
	public List<GenTable> findByTableNames(String tableNames) {
		return genTableDao.findByTableNames(tableNames);
	}

	/**
	 * @desc 获取物理数据表列表
	 * @param genTable 物理数据表
	 * @return
	 */
	@Override
	public List<GenTable> findTableListFormDb(GenTable genTable) {
		return genTableDao.findTableListFormDb(genTable);
	}

	/**
	 * @desc 获取数据表主键
	 * @param genTable  需要生成代码的数据库表结构对象
	 * @return
	 */
	@Override
	public List<String> findTablePK(GenTable genTable) {
		return genTableDao.findTablePK(genTable);
	}

	/**
	 * @desc 验证表名是否可用，如果已存在，则返回false
	 * @param tableName 数据库表名
	 * @return
	 */
	@Override
	public boolean checkTableName(String tableName) {
		if (StringUtils.isBlank(tableName)) {
			return true;
		}

		GenTable genTable = genTableDao.findByTableName(tableName);
		return BeanUtils.isNull(genTable);
	}

	/**
	 * @desc 获取物理数据表列表
	 * @param genTable 数据表对象
	 * @return
	 */
	@Override
	public GenTable getTableFormDb(GenTable genTable) {
		// 如果有表名，则获取物理表
		if (StringUtils.isNotBlank(genTable.getTableName())) {

			List<GenTable> list = genTableDao.findTableListFormDb(genTable);
			if (list.size() > 0) {

				// 如果是新增，初始化表属性
				if (StringUtils.isZero(genTable.getId())) {
					genTable = list.get(0);
					// 设置字段说明
					if (StringUtils.isBlank(genTable.getComments())) {
						genTable.setComments(genTable.getTableName());
					}

					// 获取数据库表名,并根据字典表配置,获取表名的简写
					String simpleTableName = StringUtils.getSimpleTableName(sysDictDao.findTableNamesByType("tablePrefix"), genTable.getTableName());
					genTable.setClassName(StringUtils.toCapitalizeCamelCase(simpleTableName)); 				// 类名(第一个字母大写)，如：sys_user => SysUser
				}

				// 添加新列
				List<GenTableColumn> columnList = genTableColumnDao.findTableColumnList(genTable);
				for (GenTableColumn column : columnList) {
					boolean isNew = false;
					for (GenTableColumn e : genTable.getColumnList()) {
						if (e.getColumnName().equals(column.getColumnName())) {
							isNew = true;
						}
					}
					if (!isNew) {
						genTable.getColumnList().add(column);
					}
				}

				// 删除已删除的列
				for (GenTableColumn e : genTable.getColumnList()) {
					boolean isDel = false;
					for (GenTableColumn column : columnList) {
						if (column.getColumnName().equals(e.getColumnName())) {
							isDel = true;
						}
					}
					if (!isDel) {
						e.setDelFlag(GenTableColumn.DEL_FLAG_DELETE);
					}
				}

				// 获取主键
				genTable.setPkList(genTableDao.findTablePK(genTable));

				// 初始化列属性字段
				GenUtils.initColumnField(genTable);
			}
		}
		return genTable;
	}

	/**
	 * @desc 保存/更新生成方案信息持久化对象
	 * @param genTable 业务表信息
	 * @param userId 操作人
	 * @return
	 */
	@Override
	@Transactional(rollbackFor={RuntimeException.class, Exception.class, Throwable.class})
	public int doEdit(GenTable genTable, String userId) {
		int result = 0;

		if(StringUtils.isZero(genTable.getId())) {
			genTable.setCreateBy(userId);
			genTable.setCreateDate(DateUtils.formatDate(new Date(), DateUtils.TIMESTAMP_PATTERN));
			genTable.preInsert();
			genTableDao.insertSelective(genTable);
		} else {
			genTable.setUpdateBy(userId);
			genTable.setUpdateDate(DateUtils.formatDate(new Date(), DateUtils.TIMESTAMP_PATTERN));
			genTable.preUpdate();
			genTableDao.updateByPrimaryKeySelective(genTable);
		}

		// 保存列
		for (GenTableColumn column : genTable.getColumnList()) {
			if(StringUtils.isNull(column.getColumnName())) continue;

			/* 设置列对应的表信息 */
			column.setGenTable(genTable);
			column.setGenTableId(genTable.getId());

			if (StringUtils.isZero(column.getId())) {
				column.setCreateBy(userId);
				column.setCreateDate(DateUtils.formatDate(new Date(), DateUtils.TIMESTAMP_PATTERN));
				column.preInsert();
				result += genTableColumnDao.insertSelective(column);
			} else {
				column.setUpdateBy(userId);
				column.setUpdateDate(DateUtils.formatDate(new Date(), DateUtils.TIMESTAMP_PATTERN));
				column.preUpdate();
				result += genTableColumnDao.updateByPrimaryKeySelective(column);
			}
		}
		return result;
	}

	/**
	 * @desc @desc 根据数据库表名(多个表名,用,进行分割),获取对应的表的注释信息串
	 * @param tableNames 数据库表名(多个表名,用,进行分割)
	 * @return
	 */
	@Override
	public String getTableCommentsByTableNames(String tableNames) {
		// 根据方案中的需要生成的表名获取对应的表注释信息
		StringBuffer tableComments = new StringBuffer();
		List<GenTable> tables = genTableDao.findByTableNames(StringUtils.replaceSrcTpDest("'"+tableNames+"'", ",", "', '"));
		for(GenTable table : tables) {
			tableComments.append(table.getComments()).append(", ");
		}
		return StringUtils.sideTrimEnd(tableComments.toString(), ",");
	}
}